package cn.pku.sirx.snad.ad.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.pku.sirx.snad.ad.dao.IDao;

/**
 * @author WangXiao
 */
public abstract class DaoImpl<T> extends HibernateDaoSupport implements IDao<T> {

    public DaoImpl(Class<T> targetClass) {
        if (targetClass == null) {
            throw new NullPointerException("target class SHOULD NOT be null");
        }
        this.targetClass = targetClass;
    }

    public Serializable insert(T object) {
        return object == null ? null : getHibernateTemplate().save(object);
    }

    public void update(T object) {
        if (object != null) {
            getHibernateTemplate().update(object);
        }
    }

    public void delete(T object) {
        if (object != null) {
            getHibernateTemplate().delete(object);
        }
    }

    public void delete(Long id) {
        if (id != null) {
            T object = get(id);
            if (object != null) {
                delete(object);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public T get(Long id) {
        return (T) (id == null ? null : getHibernateTemplate().get(targetClass,
                id));
    }

    @SuppressWarnings("unchecked")
    public T get(String id) {
        return (T) (id == null ? null : getHibernateTemplate().get(targetClass,
                id));
    }

    protected List<T> get(DetachedCriteria criteria) {
        return get(criteria, 0, -1);
    }

    @SuppressWarnings("unchecked")
    protected List<T> get(DetachedCriteria criteria, int firstResult,
            int maxResults) {
        if (criteria == null) {
            criteria = DetachedCriteria.forClass(targetClass);
        }
        return getHibernateTemplate().findByCriteria(criteria, firstResult,
                maxResults);
    }

    protected int getCount(DetachedCriteria criteria) {
        if (criteria == null) {
            criteria = DetachedCriteria.forClass(targetClass);
        }
        criteria.setProjection(Projections.rowCount());
        return (Integer) getHibernateTemplate().findByCriteria(criteria).get(0);
    }

    protected Class<T> targetClass;

}
